package com.mh.entity;

import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

//特殊实体类,该类为UserDetails接口的实现类
//用于方法返回类型为UserDetails时返回该类的对象(实现类)
public class LoginUser implements UserDetails {

    //加入实体类对象属性
    private SysUser user;
    //存储权限的集合
    private List<String> permissions; //新增
    //存储角色集合
    private List<String> roles; //新增

    //有无参,set(),get()
    public LoginUser() {
    }
    public LoginUser(SysUser user) {
        this.user = user;
    }
    public LoginUser(List<String> permissions) {
        this.permissions = permissions;
    }
    public LoginUser(SysUser user, List<String> permissions) {
        this.user = user;
        this.permissions = permissions;
    }
    public LoginUser(SysUser user, List<String> permissions, List<String> roles) {
        this.user = user;
        this.permissions = permissions;
        this.roles = roles;
    }
    public List<String> getRoles() {
        return roles;
    }
    public void setRoles(List<String> roles) {
        this.roles = roles;
    }
    public SysUser getUser() {
        return user;
    }
    public void setUser(SysUser user) {
        this.user = user;
    }
    public List<String> getPermissions() {
        return permissions;
    }
    public void setPermissions(List<String> permissions) {
        this.permissions = permissions;
    }
    //实现UserDetails的抽象方法
    //1. 用于获取用户被授予的权限(关键),可以用于实现访问控制
    /** getAuthorities()方法本身是一个getter方法 --> 方法调用时会序列化
     *  反序列化时 FastJSON 会尝试调用setAuthorities方法,如果该方法不存在,会抛出NoSuchMethodException异常
     *  @ JSONField(serialize = false, deserialize = false): 完全忽略getAuthorities()方法的序列化和反序列化
     *  serialize = false: 序列化时会被忽略,即不会将getAuthorities()方法的返回值包含在生成的JSON数据中
     *  deserialize = false: 反序列化时会被忽略，即不会尝试从JSON数据中解析并setAuthorities
     */
    @Override
    /** Collection<? extends GrantedAuthority>
     *  返回类型为Collection集合,泛型指定了上限<? extends GrantedAuthority>
     *  返回类型只能是GrantedAuthority的本身或者子类(/实现类)
     *  这里用SimpleGrantedAuthority(实现类)作为返回类型
     */
    @JSONField(serialize = false, deserialize = false)
    public Collection<? extends GrantedAuthority> getAuthorities() {

        List<SimpleGrantedAuthority> authorities = new ArrayList<>();

        //权限类型转换(String-->SimpleGrantedAuthority)
        //方式2: JDK1.8新特性,Stream流
        List<SimpleGrantedAuthority> permsAuth =
                permissions.stream()
                        .map(perm -> new SimpleGrantedAuthority(perm))
                        .collect(Collectors.toList());

        //角色类型转换(String-->SimpleGrantedAuthority)
        //角色判断的方法底层是会拼接上前缀"ROLE_", 因此在此拼接字符串
        List<SimpleGrantedAuthority> rolesAuth =
                roles.stream()
                        .map(role -> new SimpleGrantedAuthority("ROLE_"+role))
                        .collect(Collectors.toList());

        //List集合的方法,将权限集合&角色集合添加到大集合(authorities)中
        authorities.addAll(permsAuth);
        authorities.addAll(rolesAuth);

        return authorities;
    }
    //2. 获取用户密码,进行密码验证
    @Override
    public String getPassword() {
        return user.getPassword();
    }
    //3. 获取用户名
    @Override
    public String getUsername() {
        return user.getUserName();
    }
    //4. 用于判断用户的账户是否过期
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    //5. 用于判断用户的账户是否被锁定
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    //6. 用于判断用户的凭证是否过期
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    //7. 用于判断用户是否已经激活
    @Override
    public boolean isEnabled() {
        return true;
    }
}
